<template>
  <div ref="lineChart" :class="{ 'no-data': !data.length }">
    <span v-if="!data.length">暂无数据</span>
  </div>
</template>
<script>
import * as echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/line';
import 'echarts/lib/component/title';
import 'echarts/lib/component/grid';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/legend';
import 'echarts/lib/component/markPoint';
import { getScale } from '@/utils/rem';
// import { getAlgorithmResult } from '@/api/general';
import { adaptive } from '../adaptive';

export default {
  name: 'LineChart',
  props: {
    grid: {
      type: Object,
      default: () => ({}),
    },
    title: { // 右上角主标题
      type: String,
      default: () => '',
    },
    data: { // 数据（接口直接取出的数据）
      type: Array,
      default: () => [],
      required: true,
    },
    xAxisKey: { // 类目轴key值
      type: String,
      default: () => 'name',
    },
    valueKeys: { // y轴数据key值
      type: Array,
      default: () => [],
      required: true,
    },
    seriesOption: { // 不同系列的配置项，封装时会拼到series内
      type: Object,
      default: () => ({}),
    },
    axisAdaptive: { // 坐标轴是否从0开始或者使用adaptive的方法取最大最小值划分为5份
      type: Boolean,
      default: () => false,
    },
    showLegend: { // 是否展示图例
      type: Boolean,
      default: () => true,
    },
    xAxisLabel: {
      type: Object,
      default: () => ({}),
    },
    colors: { // 颜色集
      type: Array,
      default: () => window.global.ECHART_COLORS,
    },
    themeColor: { // 主题颜色，包括图例、坐标轴等颜色
      type: String,
      default: () => 'default',
    },
    unit: { // 单位
      type: String,
      default: () => '',
    },
    showSplitLine: { // 是否显示SplitLine
      type: Boolean,
      default: () => true,
    },
    rem: { // 是否使用rem适配
      type: Boolean,
      default: () => true,
    },
    maxValue: { // 最大值
      type: Number,
      default: () => null,
    },
  },
  data() {
    return {
      scale: this.rem ? getScale() : 1,
      chart: null,
      option: {},
    };
  },
  watch: {
    data: {
      handler: function (newVal, oldVal) {
        this.updateChart();
      },
      immediate: false,
      deep: true,
    },
  },
  mounted() {
    this.initChart();
    this.updateChart();
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$refs.lineChart);
      this.option = {
        grid: {
          top: this.showLegend ? 100 * this.scale : 60 * this.scale,
          left: 0,
          right: 0,
          bottom: 0,
          containLabel: true,
          ...this.grid,
        },
        title: {
          show: this.title.length > 0,
          text: this.title,
          left: 'center',
          textStyle: {
            color: '#000',
            fontSize: 20 * this.scale,
          },
        },
        legend: {
          show: this.showLegend,
          top: 30 * this.scale,
          right: 0,
          data: [],
          textStyle: {
            color: this.themeColor === 'default' ? '#000' : this.themeColor,
            fontSize: 16 * this.scale,
          },
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            lineStyle: {
              type: 'dashed',
              color: 'rgba(0, 0, 0, 0.15)',
            },
          },
          textStyle: {
            fontSize: 16 * this.scale,
            fontWeight: 'bold',
          },
          formatter: (params) => {
            let tooltip = `<div>${params[0].name}</div>`;
            params.forEach((item) => {
              tooltip += `<div>
                ${item.marker}
                <span style="color: #666;">${item.seriesName}</span>
                <span style="float: right;margin-left: 20px;color: #666;">${item.value || item.value === 0 ? item.value : '-'}${this.unit}</span>
              </div>`;
            });
            return tooltip;
          },
          backgroundColor: 'rgba(255, 255, 255, 0.8)',
          borderWidth: 1,
          borderColor: '#E5E5E5',
          extraCssText: 'box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);',
        },
        xAxis: {
          type: 'category',
          boundaryGap: true,
          axisTick: {
            show: true,
            lineStyle: {
              color: this.themeColor === 'default' ? 'rgba(0, 0, 0, 0.45)' : this.themeColor,
            },
          },
          axisLine: {
            lineStyle: {
              color: this.themeColor === 'default' ? 'rgba(0, 0, 0, 0.45)' : this.themeColor,
            },
          },
          axisLabel: {
            interval: 0,
            margin: 14 * this.scale,
            fontSize: 16 * this.scale,
            color: this.themeColor === 'default' ? '#171F36' : this.themeColor,
            ...this.xAxisLabel,
          },
          data: [],
        },
        yAxis: {
          type: 'value',
          name: this.unit,
          nameTextStyle: {
            fontSize: 16 * this.scale,
            color: this.themeColor === 'default' ? 'rgba(0, 0, 0, 0.45)' : this.themeColor,
          },
          axisTick: {
            show: false,
          },
          axisLine: {
            show: false,
          },
          axisLabel: {
            margin: 10 * this.scale,
            fontSize: 16 * this.scale,
            color: this.themeColor === 'default' ? 'rgba(0, 0, 0, 0.45)' : this.themeColor,
          },
          splitLine: {
            show: this.showSplitLine,
            lineStyle: {
              type: 'dashed',
              color: this.themeColor === 'default' ? 'rgba(0, 0, 0, 0.3)' : this.themeColor,
              opacity: 0.25,
            },
          },
        },
        color: this.colors,
        series: [],
      };
      this.chart.on('click', (params) => {
        if (params.componentType === 'series') this.$emit('click', params);
      });
    },
    async updateChart() {
      this.option.title.text = this.title;
      this.option.title.show = this.title.length > 0;
      if (this.showLegend) {
        let legend = [];
        this.valueKeys.forEach((valueKey) => { legend.push(valueKey.name); });
        this.option.legend.data = legend;
      }
      if (this.maxValue) this.option.yAxis.max = this.maxValue;
      if (this.axisAdaptive) {
        let max;
        let min;
        this.data.forEach((item) => {
          this.valueKeys.forEach((valueKey) => {
            if (typeof (max) === 'undefined' || max < item[valueKey.key]) max = item[valueKey.key];
            if (typeof (min) === 'undefined' || min > item[valueKey.key]) min = item[valueKey.key];
          });
        });
        if (max > min) {
          let adapt = adaptive(max, min);
          // let adapt = {};
          // await getAlgorithmResult({ max, min }).then((res) => { adapt = res; });
          this.option.yAxis = {
            ...this.option.yAxis,
            ...adapt,
          };
        }
      }
      let xAxis = [];
      let series = [];
      this.valueKeys.forEach((item, index) => {
        series.push({
          type: 'line',
          symbol: 'circle',
          symbolSize: 8 * this.scale,
          lineStyle: {
            width: 2 * this.scale,
          },
          itemStyle: {
            color: (params) => this.colors[params[this.colorful ? 'dataIndex' : 'seriesIndex']] || this.colors[0],
          },
          data: [],
        });
      });
      this.data.forEach((item) => {
        xAxis.push(item[this.xAxisKey]);
        this.valueKeys.forEach((valueKey, index) => {
          series[index].name = valueKey.name;
          series[index].data.push(item[valueKey.key]);
          series[index] = { ...series[index], ...this.seriesOption[valueKey.name] };
        });
      });
      this.option.xAxis.data = xAxis;
      this.option.series = series;
      this.chart.clear();
      this.chart.setOption(this.option);
    },
  },
  beforeDestroy() {
    if (this.chart) {
      this.chart.dispose();
      this.chart = null;
    }
  },
};
</script>

<style lang="scss" scoped>
.no-data {
  font-size: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
